import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_performance/firebase_performance.dart';
import 'package:firebase_plugin/core/wrap/metric_wrapper.dart';
import 'package:firebase_plugin/core/wrap/trace_wrapper.dart';
import 'package:flutter/foundation.dart';

///
/// Created by hai046 on 2022/7/26.
///

class FirebasePerformanceUtils {
  static FirebasePerformance? _firebasePerformance;

  static void init() async {
    try {
      _firebasePerformance =
          FirebasePerformance.instanceFor(app: Firebase.app());
      print('init FirebaseUtils success !!!');
    } on FirebaseException catch (e) {
      print(e);
    }
  }

  static MetricWrapper? newHttpMetric(
      String metricUrl, String method, Map<String, String> attributes) {
    if (kIsWeb) {
      return null;
    }
    var firebaseHttpMethod = HttpMethod.values.firstWhere(
        (type) =>
            type.toString().split('.').last.toLowerCase() ==
            method.toLowerCase(),
        orElse: () => HttpMethod.Get);
    try {
      var metric =
          _firebasePerformance?.newHttpMetric(metricUrl, firebaseHttpMethod);
      attributes?.forEach((key, value) {
        metric?.putAttribute(key, value);
      });
      // metric?.putAttribute("userId", '${UserInfoRepo.userId}');
      // metric?.putAttribute("userIp", '${UserInfoRepo.userIp}');
      // metric?.putAttribute("deviceId", DeviceInfoUtils.getDeviceId());
      return MetricWrapper(metric);
    } on FirebaseException catch (e) {
      print(e);
    }
    return null;
  }

  static TraceWrapper? newTrace(String name, Map<String, String> attributes) {
    if (kIsWeb) {
      return null;
    }
    try {
      var trace = _firebasePerformance?.newTrace(name);
      attributes.forEach((key, value) {
        trace?.putAttribute(key, value);
      });
      //TODO wangchao
      // trace?.putAttribute("userId", '${UserInfoRepo.userId}');
      // trace?.putAttribute("userIp", '${UserInfoRepo.userIp}');
      // trace?.putAttribute("deviceId", DeviceInfoUtils.getDeviceId());
      return TraceWrapper(trace);
    } on FirebaseException catch (e) {
      print(e);
    }
    return null;
  }

  static final Map<String, MetricWrapper?> _unityHttpMetrics =
      <String, MetricWrapper?>{};

  static void unityNewHttpMetricStart(
      Map<String, dynamic> map, Map<String, String> userAttributes) {
    String id = '${map['id']}';
    String url = map['url'];
    String httpMethod = map['httpMethod'];
    var newHttpMetric =
        FirebasePerformanceUtils.newHttpMetric(url, httpMethod, userAttributes);
    if (newHttpMetric != null) {
      if (map.containsKey("requestPayloadSize")) {
        newHttpMetric.requestPayloadSize =
            double.parse('${map['requestPayloadSize']}').toInt();
      }
      if (map.containsKey("attributes")) {
        var attribute = map['attributes'];
        attribute.forEach((key, value) {
          newHttpMetric.putAttribute(key, value);
        });
      }
      newHttpMetric.putAttribute("from", "unity");
      newHttpMetric.start();
      _unityHttpMetrics[id] = newHttpMetric;
      print('firebase unityNewHttpMetricStart $map');
    }
  }

  static void unityNewHttpMetricStop(Map<String, dynamic> map) {
    String id = '${map['id']}';
    if (_unityHttpMetrics.containsKey(id)) {
      var unityHttpMetric = _unityHttpMetrics.remove(id);
      if (map.containsKey("attributes")) {
        var attribute = map['attributes'];
        attribute.forEach((key, value) {
          unityHttpMetric?.putAttribute(key, value);
        });
      }

      if (map.containsKey("httpResponseCode")) {
        unityHttpMetric?.httpResponseCode =
            double.parse('${map['httpResponseCode']}').toInt();
      }
      if (map.containsKey("responsePayloadSize")) {
        unityHttpMetric?.responsePayloadSize =
            double.parse('${map['responsePayloadSize']}').toInt();
      }
      unityHttpMetric?.stop();
      print('firebase unityNewHttpMetricStop $map');
    } else {
      print('Not found unityNewHttpMetricStop, please create first! ');
    }
  }

  static final Map<String, TraceWrapper?> _unityTraces =
      <String, TraceWrapper?>{};

  static void unityTraceStart(
      Map<String, dynamic> map, Map<String, String> userAttributes) {
    String name = map['name'];
    String id = '${map['id']}';
    var newTrace =
        FirebasePerformanceUtils.newTrace('unity_$name', userAttributes);
    if (newTrace != null) {
      if (map.containsKey("metrics")) {
        var metrics = map['metrics'];
        metrics.forEach((key, value) {
          newTrace.incrementMetric(key, double.parse('$value').toInt());
        });
      }
      if (map.containsKey("attributes")) {
        var attribute = map['attributes'];
        attribute.forEach((key, value) {
          newTrace.putAttribute(key, value);
        });
      }
      newTrace.start();
      _unityTraces[id] = newTrace;
      print('firebase unityTraceStart $map');
    }
  }

  static void unityTraceStop(Map<String, dynamic> map) {
    String id = '${map['id']}';
    if (_unityTraces.containsKey(id)) {
      var trace = _unityTraces.remove(id);
      if (map.containsKey("metrics")) {
        var metrics = map['metrics'];
        metrics.forEach((key, value) {
          trace?.incrementMetric(key, double.parse('$value').toInt());
        });
      }
      if (map.containsKey("attributes")) {
        var attribute = map['attributes'];
        attribute.forEach((key, value) {
          trace?.putAttribute(key, value);
        });
      }
      trace?.stop();
      print('firebase unityTraceStop $map');
    } else {
      print('Not found unityTraceStop, please create first! ');
    }
  }
}
